package io;

import java.io.*;

/**
 * @author 26029
 * @date 2025/4/16
 * @description
 */
public class LearnJDKSerialize {
    public static void main(String[] args) throws IOException, ClassNotFoundException {
        // 不推荐jdk序列化:安全漏洞,不跨语言,性能差

        // 父类是 Serializable，所有子类都可以被序列化。
        // 子类是 Serializable ，父类不是，则子类可以正确序列化，但父类的属性不会被序列化（不报错，数据丢失）。
        // 反序列化时，如果对象的属性有修改或删减，则修改的部分属性会丢失，但不会报错。
        final String filename1 = "D:/project/learnJava/src/main/java/io/text.dat";
        Person person = new Person("小王", 311, 123);
        System.out.println(person); // Person{name='小王', age=311, testTransient=123}

        // 序列化
        ObjectOutputStream out = new ObjectOutputStream(new FileOutputStream(filename1));
        out.writeObject(person);
        out.close();
        // 反序列化
        ObjectInputStream in = new ObjectInputStream(new FileInputStream(filename1));
        Person p = (Person) in.readObject();
        in.close();

        System.out.println(p); // Person{name='小王', age=311, testTransient=null}

        // Externalize 接口: Animal类需要有无参构造函数,因为使用Externalize时,jvm会通过无参构造器创建空对象,然后用readExternal()填充数据
        final String filename2 = "D:/project/learnJava/src/main/java/io/externalize.txt";
        Animal animal = new Animal("喵", 3);
        System.out.println(animal);

        // 序列化
        ObjectOutputStream out2 = new ObjectOutputStream(new FileOutputStream(filename2));
        out2.writeObject(animal);
        out2.close();
        // 反序列化
        ObjectInputStream in2 = new ObjectInputStream(new FileInputStream(filename2));
        Animal a = (Animal) in2.readObject();
        in2.close();

        System.out.println(a);
    }
}

class Person implements Serializable {
    @Serial
    private static final long serialVersionUID = 1L;
    private String name;
    private Integer age;

    private transient Integer testTransient;

    public Person(String name, Integer age, Integer testTransient) {
        this.age = age;
        this.name = name;
        this.testTransient = testTransient;
    }

    public Person() {
    }

    @Override
    public String toString() {
        return "Person{" + "name='" + name + '\'' + ", age=" + age + ", testTransient=" + testTransient + '}';
    }
}

class Animal implements Externalizable {
    private String name;
    private int age;

    public Animal(String name, int age) {
        this.name = name;
        this.age = age;
    }

    public Animal() {
    }

    @Override
    public void writeExternal(ObjectOutput out) throws IOException {
        out.writeUTF(name);
        out.writeInt(age);
    }

    @Override
    public void readExternal(ObjectInput in) throws IOException, ClassNotFoundException {
        name = in.readUTF();
        age = in.readInt();
    }

    @Override
    public String toString() {
        return "Animal{" + "name='" + name + '\'' + ", age=" + age + '}';
    }
}